package net.mksat.gan.keysmanager.connection;

import android.os.Environment;
import android.util.Log;
import android.content.ContextWrapper;
import net.mksat.gan.keysmanager.util.BitmapUtil;
import ua.edu.nuos.androidtraining2013.kms.dto.CatalogContainer;
import ua.edu.nuos.androidtraining2013.kms.dto.JournalEntryContainer;
import ua.edu.nuos.androidtraining2013.kms.dto.PermissionContainer;
import ua.edu.nuos.androidtraining2013.kms.dto.PersonnelContainer;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import static ua.edu.nuos.androidtraining2013.kms.util.JSONUtil.fromJson;
import static ua.edu.nuos.androidtraining2013.kms.util.JSONUtil.toJSON;

/**
 * Created by sergey on 7/7/14.
 */
public class ServerConnection {
    private static final String TAG_LOG = ServerConnection.class.getName();

    private static String inputStreamToString(InputStream inputStream) throws IOException {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String read = bufferedReader.readLine();
        while (read != null) {
            stringBuilder.append(read);
            read = bufferedReader.readLine();
        }
        return stringBuilder.toString();
    }

    public static CatalogContainer connectionParser(String httpURL) throws IOException {
        URL url = new URL(httpURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(60000);
        connection.setReadTimeout(60000);
        InputStream inputStream = connection.getInputStream();
        String jsonFromURL = inputStreamToString(inputStream);
        inputStream.close();
        if (connection.getResponseCode() >= 400) {
            throw new IOException();
        }
        connection.disconnect();
        return fromJson(jsonFromURL, CatalogContainer.class);
    }

    public static boolean outputJournalEntry(String httpURL, List<JournalEntryContainer> list) {
        if (list.size() != 0) {
            HttpURLConnection connection = null;
            try {
                URL url = new URL(httpURL);
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestProperty("Content-Type", "application/json");
                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                connection.connect();
                OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
                wr.write(toJSON(list));
                wr.flush();
                wr.close();
                Log.i(TAG_LOG, String.valueOf(connection.getResponseCode()));
                if (connection.getResponseCode() >= 400) {
                    return false;
                }
            } catch (IOException e) {
                return false;
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }

        }
        return true;
    }

    /**
     * Downloads file and store it in a file object.
     *
     * @param file File object where file should be downloaded
     */
    public static boolean downloadFile(HttpURLConnection connection, File file) {

        boolean result = false;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        long nread = 0L;

        try {
            Log.v(TAG_LOG, String.format("downloadFile() - Used '%s' to fetch an file from REST server", connection.getURL().toString()));
            int responseCode = connection.getResponseCode();
            bis = new BufferedInputStream(connection.getInputStream()); //<проверьте здесь responsecode == 200 >
            fos = new FileOutputStream(file);
            nread = writeToFileStream(bis, fos);
            Log.v(TAG_LOG, String.format("downloadFile() - Downloaded file size %d bytes", nread));
        } catch (IOException e) {
            Log.e(TAG_LOG, "downloadFile() - Error during IO operation", e);
            // throw new NetworkErrorException(); ?????????????????????????????????????????????????????????????????
        } finally {
            closeStream(fos, "downloadFile() - Can't close destination file");
            closeStream(bis, "downloadFile() - Can't close input stream");
            if (connection != null)
                connection.disconnect();
        }
        if (file.exists()) {
            if (nread == 0) {
                Log.v(TAG_LOG, "downloadFile() - Erasing empty downloaded file.");
                file.delete();
            } else {
                result = true;
            }
        }
        return result;
    }

    private static long writeToFileStream(InputStream bis, FileOutputStream fos) {
        long nread = 0L;
        byte[] buf = new byte[1024];
        int n;
        try {
            while ((n = bis.read(buf)) > 0) {
                fos.write(buf, 0, n);
                nread += n;
                if (nread > 10 * 1024 * 1024) { // 10MB
                    throw new IllegalArgumentException(); // <--- решите здесь что делать если файл слишком большлй
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return nread;
    }

    /**
     * Close Input-,Outputstream. If stream is null nothing will be done.
     *
     * @param stream  Stream to be closed
     * @param message Log message if exception occurs when closing
     */
    private static void closeStream(Object stream, String message) {
        if ((stream == null) || (!(stream instanceof InputStream) && !(stream instanceof OutputStream))) {
            return;
        }
        try {
            if (stream instanceof InputStream) {
                ((InputStream) stream).close();
            } else {
                ((OutputStream) stream).close();
            }
        } catch (IOException e) {
            Log.e(TAG_LOG, message, e);
        }
    }
}
